package com.gouwudai.gobbs.file;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;

import com.gouwudai.gobbs.common.Arguments;
import com.gouwudai.gobbs.vo.UserLoginVO;
import com.litt.core.common.Utility;
import com.litt.core.exception.BusiException;
import com.litt.core.exception.NotLoginException;
import com.litt.core.file.ajaxupload.MonitoredDiskFileItemFactory;
import com.litt.core.file.ajaxupload.UploadListener;

public class UploadFile
{
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(UploadFile.class);

	private String tempPath;	//临时目录
	private String uploadPath ; //存放文件的路径
	private String uploadType = "0";	//上传文件的类型:0-公用文件，1-公用图片，2-个人文件，3-个人图片
	private long fileTotalSize = 0; //用户剩余空间
	
	public UploadFile()
	{	
		uploadPath = Arguments.getRootPath()+"/uploadfiles/";
		tempPath = Arguments.getRootPath()+"/uploadfiles/temp/"; 		
	}

    /**
     * 文件上传
     * @param request
     * @return
     * @throws ServletException
     * @throws IOException
     */
	public String upload(HttpServletRequest request) throws BusiException, ServletException, IOException {
		String errorMsg = "";
		
        HttpSession session = request.getSession();        
		UserLoginVO userLogin = (UserLoginVO)session.getAttribute("USER_LOGIN"); //从SESSION中获取登陆用户的信息
        if(userLogin==null)
            throw new NotLoginException("用户尚未登陆！");
        String loginId = userLogin.getLoginId();
        if(Utility.isEmpty(loginId))
            throw new NotLoginException("用户尚未登陆！");
        
        //文件夹不存在就自动创建：        
        File tempDir = new File(tempPath);
        if(!tempDir.isDirectory())
            tempDir.mkdirs(); 
        //开始上传
		try {
            UploadListener listener = new UploadListener(request, 30);

            // Create a factory for disk-based file items
            DiskFileItemFactory factory = new MonitoredDiskFileItemFactory(listener);
            //设置内存阀值，超过后写入临时文件
            factory.setSizeThreshold(Constant.UPLOAD_SIZE_THRESHOLD);
            //设置临时文件存储位置
            factory.setRepository(tempDir);
            ServletFileUpload upload = new ServletFileUpload(factory);
            //设置单个文件的最大上传size:100M
            upload.setFileSizeMax(Constant.MAX_EACH_FILE_UPLOAD_SIZE);
            //设置整个request的最大size:100M
            upload.setSizeMax(Constant.MAX_ONCE_UPLOAD_SIZE);
	        // 得到所有的文件:
            
	        List fileItems = upload.parseRequest(request);
            //预处理表单
            for(int i=0;i<fileItems.size();i++) 
            {
               FileItem fi = (FileItem)fileItems.get(i);
               if (fi.isFormField()) //这是用来确定是否为文件属性            
               {
                   String fieldName = fi.getFieldName(); //这里取得表单名
                   String fieldValue = fi.getString("UTF-8"); //这里取得表单值
                   logger.info("表单字段 - "+fieldName+",值 - "+fieldValue);
                   if(logger.isDebugEnabled())
                   {
                       logger.debug("表单字段 - "+fieldName+",值 - "+fieldValue);
                   }
                   if(fieldName.equals("uploadType"))
                   {
                       uploadType = fieldValue;
                       if(uploadType.equals("0"))  //公用文件
                       {
                           uploadPath += "global/files";
                       }
                       else if(uploadType.equals("1"))  //公用图片
                       {
                           uploadPath += "global/pic";
                       }
                       if(uploadType.equals("2"))  //个人文件
                       {
                           uploadPath = uploadPath+"userspace/"+loginId+"/files";
                       }
                       if(uploadType.equals("3"))  //个人图片
                       {
                           uploadPath = uploadPath+"userspace/"+loginId+"/pic";
                       }
                       if(logger.isDebugEnabled())
                       {
                           logger.debug("上传文件用户 - "+loginId);
                           logger.debug("文件上传路径 - "+uploadPath);   
                       }
                       // 文件夹不存在就自动创建：
                       File uploadDir = new File(uploadPath);
                       if(!uploadDir.isDirectory())
                           uploadDir.mkdirs();        
                       
                   }
               }  
            }    
	        // 依次处理每一个文件：
            for(int i=0;i<fileItems.size();i++) 
            {
                FileItem fi = (FileItem)fileItems.get(i);
				if (!fi.isFormField()) //这是用来确定是否为文件属性, 
				{					 
					String fileName = fi.getName(); // 返回文件名包括客户机路径
					long fileSize = fi.getSize()/1024;//文件大小
					if (fileName != null) 
					{						
                        int remainSize = userLogin.getUpfileSize()-userLogin.getUpfileUsedSize();
                        if(logger.isDebugEnabled())
						{
							logger.debug("上传文件的名称 - "+fileName); // 打印文件表单名
                            logger.debug("剩余空间大小 - "+remainSize); // 打印文件表单名
						}					
                        
						if(remainSize<fileSize)
						{
							errorMsg = "您的空间已满、或者你选择的文件过大，不能执行上传(您的上传的文件大小约为：";
							errorMsg += fileSize;
							errorMsg += "，您的剩余上传空间约为：" + remainSize;
							errorMsg += ")";
							return errorMsg;
						}
						String ext = Utility.getFileExt(fileName);
                        String prefix = Utility.getFilePrefix(fileName);
						File file = new File(uploadPath,prefix+ext);						
						fi.write(autoRename(file,prefix,ext,0)); // 写文件到服务器.	
						fileTotalSize += fileSize;
					}
				}                 
	        }
	        // 跳转到上传成功提示页面            
	    }
	    catch(Exception e) {
	    	errorMsg = "文件上传失败 - "+e.getMessage();
	    	logger.error("文件上传失败！",e);
	    	return errorMsg;
	    }
	    return errorMsg;
	}
	
	/**
     * 自动重命名文件,文件名后加_i
     * @param file
     * @param namePrefix
     * @param ext
     * @param count
     * @return
	 */
	private static File autoRename(File file,String namePrefix,String ext,int count)
	{
		while(file.exists())
		{
			file = autoRename(new File(file.getParent(),namePrefix+"_"+(++count)+ext),namePrefix,ext,count);
		}
		return file;
	}


	public long getFileTotalSize() {
		return fileTotalSize;
	}

	public void setFileTotalSize(long fileTotalSize) {
		this.fileTotalSize = fileTotalSize;
	}

    /**
     * @return the uploadType
     */
    public String getUploadType()
    {
        return uploadType;
    }

    /**
     * @param uploadType the uploadType to set
     */
    public void setUploadType(String uploadType)
    {
        this.uploadType = uploadType;
    }
}
